#include "Player.h"

#include <DXUT.h>
#include <stdexcept>



CDXUTSDKMesh e3d::Player::s_playerWeaponMesh;
ID3D10ShaderResourceView* e3d::Player::s_playerWeaponTexture;


e3d::Player::Player(	ID3D10Device* device, ID3D10Effect* effect,
					D3DXVECTOR3 position, D3DXVECTOR3 rotation, D3DXVECTOR3 size )
:	m_device( device ),
	m_effect( effect ),
	m_position( position ), 
	m_rotation( rotation ),
	m_size( size )
{

	this->loadMeshes(device);
	
	
}

e3d::Player::~Player()
{
	this->releaseDxutMeshes(m_device);

	m_device->IASetIndexBuffer( NULL, DXGI_FORMAT_R32_UINT, 0);

}


void e3d::Player::render( ID3D10EffectTechnique* tech, const D3DXVECTOR3* camPos )
{
	/* Render instanced trees from SDK mesh
	unsigned int Offset[2] = {0,0};
	unsigned int Stride[2];
	Stride[0] = (UINT) s_dxutMeshes[0].GetVertexStride( 0, 0 );		//Per Vertex Data
	Stride[1] = sizeof(D3DXMATRIX);									//Per Instance Data
	*/

	unsigned int Offset[1] = {0};
	unsigned int Stride[1];
	Stride[0] = (UINT) s_playerWeaponMesh.GetVertexStride( 0, 0 );		//Per Vertex Data
	
	/*
	ID3D10Buffer *pVB[2] = {s_dxutMeshes[0].GetVB10(0,0), m_pInstanceVB};			// Todo: Checken: ist pInstance Pointer?
	m_device->IASetVertexBuffers( 0, 2, pVB, Stride, Offset );
	m_device->IASetIndexBuffer( s_dxutMeshes[0].GetIB10( 0 ), s_dxutMeshes[0].GetIBFormat10( 0 ), 0 );
	m_device->IASetInputLayout( m_meshLayout );
	*/

	ID3D10Buffer *pVB[1] = {s_playerWeaponMesh.GetVB10(0,0)};	
	m_device->IASetVertexBuffers( 0, 1, pVB, Stride, Offset );
	m_device->IASetIndexBuffer( s_playerWeaponMesh.GetIB10( 0 ), s_playerWeaponMesh.GetIBFormat10( 0 ), 0 );
	m_device->IASetInputLayout( m_weaponMeshLayout );


// Effect variable storing texture
	ID3D10EffectShaderResourceVariable* colTexHandle = m_effect->GetVariableByName("terrainTexture")->AsShaderResource();

	SDKMESH_SUBSET* pSubset= NULL;
	for( UINT subset = 0; subset < s_playerWeaponMesh.GetNumSubsets( 0 ); ++subset )
	{
		pSubset= s_playerWeaponMesh.GetSubset( 0, subset);	
		m_device->IASetPrimitiveTopology( s_playerWeaponMesh.GetPrimitiveType10( ( SDKMESH_PRIMITIVE_TYPE )pSubset->PrimitiveType) );

		colTexHandle->SetResource( s_playerWeaponTexture );
		//		pSubset->MaterialID
		


		tech->GetPassByName( "renderPlayerWeapon" )->Apply(0);

		//if(subset == 0)
		m_device->DrawIndexed( (UINT)pSubset->IndexCount, 0, (UINT)pSubset->VertexStart );
		
		//m_device->DrawIndexedInstanced((UINT)pSubset->IndexCount, m_numTrees, 0, (UINT)pSubset->VertexStart, 0 );
	}
}

e3d::BoundingBox e3d::Player::boundingBox() const
{
	e3d::BoundingBox bb;
	bb.bottomRightBack = D3DXVECTOR3(	m_vertices[0].position.x * m_size.x, 
										m_vertices[0].position.y * m_size.y, 
										m_vertices[0].position.z * m_size.z );

	bb.bottomRightFront = D3DXVECTOR3(	m_vertices[1].position.x * m_size.x, 
										m_vertices[1].position.y * m_size.y, 
										m_vertices[1].position.z * m_size.z );

	bb.bottomLeftFront = D3DXVECTOR3(	m_vertices[2].position.x * m_size.x, 
										m_vertices[2].position.y * m_size.y, 
										m_vertices[2].position.z * m_size.z );

	bb.bottomLeftBack = D3DXVECTOR3(	m_vertices[3].position.x * m_size.x, 
										m_vertices[3].position.y * m_size.y, 
										m_vertices[3].position.z * m_size.z );

	bb.topRightBack = D3DXVECTOR3(	m_vertices[4].position.x * m_size.x, 
									m_vertices[4].position.y * m_size.y, 
									m_vertices[4].position.z * m_size.z );

	bb.topRightFront = D3DXVECTOR3(	m_vertices[5].position.x * m_size.x, 
									m_vertices[5].position.y * m_size.y, 
									m_vertices[5].position.z * m_size.z );

	bb.topLeftFront = D3DXVECTOR3(	m_vertices[6].position.x * m_size.x, 
									m_vertices[6].position.y * m_size.y, 
									m_vertices[6].position.z * m_size.z );

	bb.topLeftBack = D3DXVECTOR3(	m_vertices[7].position.x * m_size.x, 
									m_vertices[7].position.y * m_size.y, 
									m_vertices[7].position.z * m_size.z );
	return bb;
}




bool e3d::Player::loadMeshes(ID3D10Device* pd3dDevice) {
	bool success = true;

	//s_playerWeaponMesh.Create( pd3dDevice,  L"AshTree.sdkmesh", true );
	s_playerWeaponMesh.Create( pd3dDevice,  L"models/i.sdkmesh", true );
	// mossberg.sdkmesh

	ID3D10EffectTechnique* tech = m_effect->GetTechniqueByName("PhongShading");
	

	const D3D10_INPUT_ELEMENT_DESC layout[] =
	{
		{ "POSITION",	0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD",	0, DXGI_FORMAT_R32G32_FLOAT,	0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0 },
		{ "NORMAL",		0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0 }
	};

	UINT numElements = sizeof( layout ) / sizeof( layout[0] );

	D3D10_PASS_DESC PassDesc;
	tech->GetPassByName( "renderPlayerWeapon" )->GetDesc( &PassDesc );		// renderPlayerWeapon
	if( FAILED( m_device->CreateInputLayout( layout, numElements, PassDesc.pIAInputSignature,
		PassDesc.IAInputSignatureSize, &m_weaponMeshLayout ) ) )
		throw std::logic_error("Could not create input layout");


	D3DX10_IMAGE_LOAD_INFO loadInfo;
	ZeroMemory( &loadInfo, sizeof(D3DX10_IMAGE_LOAD_INFO) );
	loadInfo.BindFlags = D3D10_BIND_SHADER_RESOURCE;
	loadInfo.Format = DXGI_FORMAT_R16G16B16A16_UNORM;

	D3DX10CreateShaderResourceViewFromFile( pd3dDevice, L"textures/weapon1.png", &loadInfo, NULL, &e3d::Player::s_playerWeaponTexture, NULL );


	return success;
}


void e3d::Player::releaseDxutMeshes(ID3D10Device* pd3dDevice) 
{
	s_playerWeaponMesh.Destroy();
	SAFE_RELEASE( m_weaponMeshLayout );
	SAFE_RELEASE( s_playerWeaponTexture );

}